home *** CD-ROM | disk | FTP | other *** search
- #include <MacHeaders>
- #include <PictUtil.h>
- #include <Memory.h>
- #include <GestaltEqu.h>
- #include <stdio.h>
- #include <string.h>
- #include "sample utilities.h"
-
-
- static OSErr CheckForTempMemory(void)
- {
- #define hasOurTempMem ((1 << gestaltTempMemSupport) | (1 << gestaltRealTempMemory) | (1 << gestaltTempMemTracked))
- OSErr error;
- long result;
-
- if( error = Gestalt(gestaltOSAttr, &result) )
- return error;
- if( (result & hasOurTempMem) == hasOurTempMem )
- return noErr;
- return memFullErr;
-
- #undef hasOurTempMem
- }
-
-
- void *GetBuffer(Handle *referencePtr, long *sizePtr, bufferType type)
- {
- OSErr error;
- Handle reference = *referencePtr;
- long requestedSize = *sizePtr;
-
- /* if we were passed an old buffer and it is still allocated and it is at least the requested size, then return the old
- buffer handle; otherwise, dispose of the old buffer and try to allocate a new one. */
-
- if( reference ) {
- long oldSize;
- if( *reference && (oldSize = GetHandleSize(reference)) >= requestedSize ) {
- if( type == bufferExactSize && oldSize != requestedSize )
- SetHandleSize(reference, requestedSize);
- goto returnReference;
- }
- DisposeHandle(reference);
- }
-
- /* try to allocate our requested size first in the multifinder heap, then in the application heap if the multifinder attempt
- fails. if we suceed, then mark the block as purgable, lock it down and return its dereferenced pointer. if we requested
- an exact size and we didn’t get it, then return nil */
-
- if( CheckForTempMemory() != noErr || (reference = TempNewHandle(requestedSize, &error)) == nil )
- reference = NewHandle(requestedSize);
- if( reference )
- goto returnReference;
- else if( type == bufferExactSize ) {
- *referencePtr = nil;
- *sizePtr = nil;
- return nil;
- }
-
- while( reference == nil ) {
- requestedSize = ((requestedSize >> 1) + 3) & 3;
- if( requestedSize == 0 )
- PostError(memFullErr);
- if( CheckForTempMemory() != noErr || (reference = TempNewHandle(requestedSize, &error)) == nil )
- reference = NewHandle(requestedSize);
- }
-
- returnReference:
- HPurge(reference);
- HLock(reference);
- *referencePtr = reference;
- *sizePtr = requestedSize;
- return *reference;
- }
-
-
- void FindScreen(screenType type, short hSize, short vSize, Rect *bounds)
- {
- bounds->top = 40;
- bounds->left = 40;
-
- bounds->right = bounds->left + hSize;
- bounds->bottom = bounds->top + vSize;
- }
-
-
- void PostError(long error)
- {
- char errorString[256];
- sprintf(&errorString[1], "an error occurred (%ld).", error);
- errorString[0] = strlen(&errorString[1]);
- DebugStr(errorString);
- }
-
-
- static pascal void ReadDiskPicture(char *destination, short count)
- {
- diskPictureRecord *picture;
- CGrafPtr currentPort;
- OSErr error;
- long bytesLeft;
-
- IfDebug(count == 0, "\pour spool proc should never be called with a count of zero");
-
- GetPort(¤tPort);
- picture = (diskPictureRecord *)((long)currentPort->grafProcs - offsetField(diskPictureRecord, procs));
-
- bytesLeft = picture->bufferStart + picture->bufferSize - picture->bufferPtr;
- while( count ) {
- long bytesRead;
-
- if( count <= bytesLeft ) {
- BlockMove(picture->bufferPtr, destination, (long)count);
- picture->bufferPtr += count;
- return;
- }
-
- BlockMove(picture->bufferPtr, destination, bytesLeft);
- destination += bytesLeft;
- count -= bytesLeft;
- picture->bufferPtr = picture->bufferStart;
- bytesLeft = bytesRead = picture->bufferSize;
- error = FSRead(picture->file, &bytesRead, picture->bufferPtr);
- if( error ) {
- short *tempPtr = (short *)(picture->bufferPtr + bytesRead);
- long counter = picture->bufferSize - bytesRead;
- short fillValue = 0x00FF;
-
- if( (long)tempPtr & 0x1 ) {
- *(char *)tempPtr = 0;
- tempPtr = (short *)((char *)tempPtr + 1);
- --counter;
- fillValue = 0xFF00;
- }
- counter /= sizeof(short);
- while( --counter >= 0 )
- *tempPtr++ = fillValue;
- }
- }
- }
-
-
- void InstallDiskPicture(diskPicture source)
- {
- CGrafPtr currentPort;
- OSErr error;
- diskPictureRecord *picture = *source;
-
- if( picture->installedPort )
- PostError(disk_picture_already_installed);
-
- HLock(source);
- GetPort(¤tPort);
-
- { long fileSize;
- void *cachePtr;
- if( error = GetEOF(picture->file, &fileSize) )
- PostError(error);
- fileSize -= 512; /* subtract the file header */
- if( cachePtr = GetBuffer((Handle *)&picture->cachedPicture, &fileSize, bufferExactSize) ) {
- if( error = SetFPos(picture->file, fsFromStart, 512) )
- PostError(error);
- if( error = FSRead(picture->file, &fileSize, cachePtr) )
- PostError(error);
- picture->installedPort = currentPort;
- return;
- }
- }
-
- picture->bufferSize = 32000;
- picture->bufferStart = GetBuffer(&picture->bufferRef, &picture->bufferSize, bufferCanBeSmaller);
- picture->bufferPtr = picture->bufferStart + picture->bufferSize;
- if( error = SetFPos(picture->file, fsFromStart, 512 + sizeof(Picture)) )
- PostError(error);
-
- picture->installedPort = currentPort;
- picture->savedProcs = currentPort->grafProcs;
- currentPort->grafProcs = &picture->procs;
- }
-
-
- void RemoveDiskPicture(diskPicture source)
- {
- diskPictureRecord *picture = *source;
- if( picture->installedPort == nil )
- PostError(disk_picture_not_installed);
-
- if( picture->cachedPicture ) {
- HUnlock(picture->cachedPicture);
- goto exit;
- }
-
- picture->installedPort->grafProcs = picture->savedProcs;
-
- HUnlock(picture->bufferRef);
- picture->bufferStart = nil;
- exit:
- picture->installedPort = nil;
- HUnlock(source);
- }
-
-
- void GetDiskPictureInfo(diskPicture source, PictInfo *result, short verb, short requestedColors, short method)
- {
- diskPictureRecord *picture;
- OSErr error;
-
- InstallDiskPicture(source);
- picture = *source;
- if( error = GetPictInfo(picture->cachedPicture ? picture->cachedPicture : picture->picture, result, verb,
- requestedColors, method, 0) ) {
- PostError(error);
- }
- RemoveDiskPicture(source);
- }
-
-
- void DrawDiskPicture(diskPicture source)
- {
- diskPictureRecord *picture;
-
- InstallDiskPicture(source);
- picture = *source;
- DrawPicture(picture->cachedPicture ? picture->cachedPicture : picture->picture, &picture->bounds);
- RemoveDiskPicture(source);
- }
-
-
- diskPicture NewDiskPicture(FSSpec *file)
- {
- OSErr error;
- long count;
- diskPicture newPicture;
- diskPictureRecord *picture;
-
- newPicture = (diskPicture)NewHandle(sizeof(diskPictureRecord));
- HLock(newPicture);
- picture = *newPicture;
- picture->owners = 1;
- picture->picture = nil;
- picture->file = 0;
- picture->cachedPicture = 0;
- picture->installedPort = 0;
- picture->bufferRef = nil;
-
- if( error = FSpOpenDF(file, fsRdPerm, &picture->file) )
- goto errorExit;
- if( error = SetFPos(picture->file, fsFromStart, 512) )
- goto errorExit;
-
- picture->picture = (PicHandle)NewHandle(sizeof(Picture));
- if( picture->picture == nil || MemError() )
- goto errorExit;
-
- HLock(picture->picture);
- count = sizeof(Picture);
- if( error = FSRead(picture->file, &count, *picture->picture) )
- goto errorExit;
- BlockMove(&(*picture->picture)->picFrame, &picture->bounds, sizeof(Rect));
- HUnlock(picture->picture);
-
- SetStdCProcs(&picture->procs);
- picture->procs.getPicProc = (void *)ReadDiskPicture;
-
- HUnlock(newPicture);
- return newPicture;
-
- errorExit:
- PostError(error);
- DisposeDiskPicture(newPicture);
- return nil;
- }
-
-
- void DisposeDiskPicture(diskPicture target)
- {
- diskPictureRecord *picture = *target;
-
- if( picture->owners > 1 ) {
- --picture->owners;
- return;
- }
-
- if( picture->picture )
- DisposeHandle(picture->picture);
- if( picture->file )
- FSClose(picture->file);
- DisposeHandle(target);
- }
-
-
- diskPicture CloneDiskPicture(diskPicture source)
- {
- (*source)->owners += 1;
- return source;
- }
-
-
- void GetDiskPictureBounds(diskPicture source, Rect *bounds)
- {
- BlockMove(&(*source)->bounds, bounds, sizeof(Rect));
- }
-